package com.liuceng.zen.web.auth.utils;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by songyu on 2016/7/26.
 */
public class TimeProcessingUtils {

  private static final Logger logger = LoggerFactory.getLogger(TimeProcessingUtils.class);

  /**
   * 获取本周第一天和最后一天,参数为空,则获取当前时间所属周的第一天和最后一天,有参数,则取参数所在周的第一天和最后一天
   * 
   * @return
   */
  public static Map<String, Object> getWeek(String times) {
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    Map<String, Object> filterMaps = new HashMap<>();
    Calendar calendarStart = Calendar.getInstance();
    try {
      if (StringUtils.isNotBlank(times)) {
        calendarStart.setTime(format.parse(times));
      } else {
        calendarStart.setTime(new Date());
      }
    } catch (ParseException e) {
      logger.error("日期格式化失败");
    }
    int dayWeek = calendarStart.get(Calendar.DAY_OF_WEEK);
    if (1 == dayWeek)
      calendarStart.add(Calendar.DAY_OF_MONTH, -1);
    calendarStart.setFirstDayOfWeek(Calendar.MONDAY);
    int day = calendarStart.get(Calendar.DAY_OF_WEEK);
    calendarStart.add(Calendar.DATE, calendarStart.getFirstDayOfWeek() - day);
    filterMaps.put("startTime", format.format(calendarStart.getTime()) + " 00:00:00");
    calendarStart.add(Calendar.DATE, 6);
    filterMaps.put("endTime", format.format(calendarStart.getTime()) + " 23:59:59");
    return filterMaps;
  }



  /**
   * 只获得日期不包含时分秒 获取本周第一天和最后一天,参数为空,则获取当前时间所属周的第一天和最后一天,有参数,则取参数所在周的第一天和最后一天
   * 
   * @return
   */
  public static Map<String, Object> getWeekNotHDS(String times) {
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    Map<String, Object> filterMaps = new HashMap<>();
    Calendar calendarStart = Calendar.getInstance();
    try {
      if (StringUtils.isNotBlank(times)) {
        calendarStart.setTime(format.parse(times));
      } else {
        calendarStart.setTime(new Date());
      }
    } catch (ParseException e) {
      logger.error("日期格式化失败");
    }
    int dayWeek = calendarStart.get(Calendar.DAY_OF_WEEK);
    if (1 == dayWeek)
      calendarStart.add(Calendar.DAY_OF_MONTH, -1);
    calendarStart.setFirstDayOfWeek(Calendar.MONDAY);
    int day = calendarStart.get(Calendar.DAY_OF_WEEK);
    calendarStart.add(Calendar.DATE, calendarStart.getFirstDayOfWeek() - day);
    filterMaps.put("startTime", format.format(calendarStart.getTime()));
    calendarStart.add(Calendar.DATE, 6);
    filterMaps.put("endTime", format.format(calendarStart.getTime()));
    return filterMaps;
  }

  /**
   * 获取某月的第一天和最后一天 如果参数为空 则获取当月的 第一天 与最后一天
   * 
   * @param times
   * @return
   */
  public static Map<String, Object> getMonth(String times) {
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    Map<String, Object> filterMaps = new HashMap<>();
    Calendar calendar = Calendar.getInstance();
    try {
      if (StringUtils.isNotBlank(times)) {
        calendar.setTime(format.parse(times));
      } else {
        calendar.setTime(new Date());
      }
    } catch (ParseException e) {
      logger.error("日期格式化失败");
    }
    calendar.set(Calendar.DAY_OF_MONTH, 1);
    filterMaps.put("startTime", format.format(calendar.getTime()) + " 00:00:00");
    calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
    filterMaps.put("endTime", format.format(calendar.getTime()) + " 23:59:59");
    return filterMaps;
  }

  /**
   * 只获得日期不包含时分秒 获取某月的第一天和最后一天 如果参数为空 则获取当月的 第一天 与最后一天
   * 
   * @param times
   * @return
   */
  public static Map<String, Object> getMonthNotHDS(String times) {
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    Map<String, Object> filterMaps = new HashMap<>();
    Calendar calendar = Calendar.getInstance();
    try {
      if (StringUtils.isNotBlank(times)) {
        calendar.setTime(format.parse(times));
      } else {
        calendar.setTime(new Date());
      }
    } catch (ParseException e) {
      logger.error("日期格式化失败");
    }
    calendar.set(Calendar.DAY_OF_MONTH, 1);
    filterMaps.put("startTime", format.format(calendar.getTime()));
    calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
    filterMaps.put("endTime", format.format(calendar.getTime()));
    return filterMaps;
  }

  /**
   * 时间分析
   * 
   * @param startTime
   * @param endTime
   * @return
   * @throws Exception
   */
  public static List<Map<String, Object>> dateAnalysis(String startTime, String endTime) {
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    if (null == startTime || startTime.equals(""))
      startTime = format.format(new Date());
    if (null == endTime || endTime.equals(""))
      endTime = format.format(new Date());
    try {
      List<Map<String, Object>> filterMaps = new ArrayList<>();
      Calendar cal1 = Calendar.getInstance();
      cal1.setTime(format.parse(startTime));
      Calendar cal2 = Calendar.getInstance();
      cal2.setTime(format.parse(endTime));
      int days =  Integer.parseInt((cal2.getTimeInMillis() - cal1.getTimeInMillis()) / (1000 * 60 * 60 * 24)+"");// 获取相差天数
      int months = days/30;// 获取相差月数
      if (days <= 30) {// 如果在一个月以内,则以天为单位
        Calendar now = Calendar.getInstance();
        now.setTime(format.parse(startTime));
        for (int i = 0; i < days + 1; i++) {
          Map<String, Object> filterMap = new HashMap<>();
          if (i == 0)
            now.set(Calendar.DATE, now.get(Calendar.DATE));
          else
            now.set(Calendar.DATE, now.get(Calendar.DATE) + 1);
          filterMap.put("startTime", format.format(now.getTime()) + " 00:00:00");
          filterMap.put("endTime", format.format(now.getTime()) + " 23:59:59");
          filterMaps.add(filterMap);
        }
        return filterMaps;// 返回查询区间结果集,调用以后直接循环该Map来获取数据
      }
      if (days > 30 && Math.abs(months) <= 3) {// 如果大于一个月并且小于一个季度,则按周统计(待确认)
        String startTimes = startTime;
        for (int i = 0; i < i + 1; i++) {
          Map<String, Object> week = getWeek(startTimes);
          Map<String, Object> filterMap = new HashMap<>();
          Date weekEnds = format.parse((String) week.get("endTime"));
          if (weekEnds.before(format.parse(endTime))) {
            if (i == 0)
              filterMap.put("startTime", startTimes + " 00:00:00");
            else
              filterMap.put("startTime", week.get("startTime"));
            filterMap.put("endTime", week.get("endTime"));
            filterMaps.add(filterMap);
            Calendar now = Calendar.getInstance();
            now.setTime(format.parse((String) week.get("endTime")));
            now.set(Calendar.DATE, now.get(Calendar.DATE) + 1);
            startTimes = format.format(now.getTime());
          } else {
            filterMap.put("startTime", week.get("startTime"));
            filterMap.put("endTime", endTime + " 23:59:59");
            filterMaps.add(filterMap);
            break;
          }
        }
        return filterMaps;// 返回查询区间结果集,调用以后直接循环该Map来获取数据
      }
      if (Math.abs(months) > 3) {// 大于一季度,按月划分
        String startTimes = startTime;
        for (int i = 0; i <= Math.abs(months); i++) {
          Map<String, Object> month = getMonth(startTimes);
          Map<String, Object> filterMap = new HashMap<>();
          if (i == 0)
            filterMap.put("startTime", startTime + " 00:00:00");
          else
            filterMap.put("startTime", month.get("startTime"));
          if (i != Math.abs(months))
            filterMap.put("endTime", month.get("endTime"));
          else
            filterMap.put("endTime", endTime + " 23:59:59");
          filterMaps.add(filterMap);
          Calendar now = Calendar.getInstance();
          now.setTime(format.parse((String) month.get("endTime")));
          now.set(Calendar.DATE, now.get(Calendar.DATE) + 1);
          startTimes = format.format(now.getTime());
        }
        return filterMaps;
      }
    } catch (ParseException e) {
      logger.error("日期格式化失败");
    }
    return null;
  }



  /**
   * 获取两个时间段以内的时间区间(以天为单位)
   *
   * @param startTime 开始时间
   * @param endTime 结束时间
   * @return
   */
  public static List<String> getDays(String startTime, String endTime) {
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    if (null == startTime || startTime.equals(""))
      startTime = format.format(new Date());
    if (null == endTime || endTime.equals(""))
      endTime = format.format(new Date());
    List<String> filterMaps = new ArrayList<>();
    try {
      Calendar cal1 = Calendar.getInstance();
      cal1.setTime(format.parse(startTime));
      Calendar cal2 = Calendar.getInstance();
      cal2.setTime(format.parse(endTime));
      int days = Integer.parseInt((cal2.getTimeInMillis() - cal1.getTimeInMillis()) / (1000 * 60 * 60 * 24)+"");// 获取相差天数
      Calendar now = Calendar.getInstance();
      now.setTime(format.parse(endTime));
      for (int i = 0; i < days + 1; i++) {
        Map<String, Object> filterMap = new HashMap<>();
        if (i == 0)
          now.set(Calendar.DATE, now.get(Calendar.DATE));
        else
          now.set(Calendar.DATE, now.get(Calendar.DATE) - 1);
//        filterMap.put("startTime", format.format(now.getTime()) + " 00:00:00");
//        filterMap.put("endTime", format.format(now.getTime()) + " 23:59:59");
        filterMaps.add(format.format(now.getTime()));
      }
      return filterMaps;
    } catch (ParseException e) {
      logger.error("日期格式化失败");
    }
    return null;
  }
    /**
     * 计算两个日期之间相差的天数
     * @param smdate 较小的时间
     * @param bdate  较大的时间
     * @return 相差天数
     * @throws ParseException
     */
    public static int daysBetween(Date smdate,Date bdate) throws ParseException
    {
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        smdate=sdf.parse(sdf.format(smdate));
        bdate=sdf.parse(sdf.format(bdate));
        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis();
        long between_days=(time2-time1)/(1000*3600*24);

        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * @param smdate 较小的时间
     * @param bdate  较大的时间
     *字符串的日期格式的计算
     */
    public static int daysBetween(String smdate,String bdate) throws ParseException{
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        cal.setTime(sdf.parse(smdate));
        long time1 = cal.getTimeInMillis();
        cal.setTime(sdf.parse(bdate));
        long time2 = cal.getTimeInMillis();
        long between_days=(time2-time1)/(1000*3600*24);
        return Integer.parseInt(String.valueOf(between_days));
    }

  /**
   * 获取默认时间
   * @return
     */
  public static Map<String, Object> getDefaultTime() {
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    Map<String, Object> filterMaps = new HashMap<>();
    Calendar startTime = Calendar.getInstance();
    startTime.setTime(new Date());
    startTime.set(Calendar.DATE, startTime.get(Calendar.DATE) - 6);
    filterMaps.put("startTime", format.format(startTime.getTime()) + " 00:00:00");
    filterMaps.put("endTime", format.format(new Date()) + " 23:59:59");
    return filterMaps;
  }

  /**
   * 获取默认时间(不含时分秒)
   * @return
   */
  public static Map<String, Object> getDefaultTimNotHDS() {
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    Map<String, Object> filterMaps = new HashMap<>();
    Calendar startTime = Calendar.getInstance();
    startTime.setTime(new Date());
    startTime.set(Calendar.DATE, startTime.get(Calendar.DATE) - 6);
    filterMaps.put("startTime", format.format(startTime.getTime()));
    filterMaps.put("endTime", format.format(new Date()));
    return filterMaps;
  }
  /**
   * 获取当前日期前一个月日期(不含时分秒)
   * @return
   */
  public static Map<String, Object> getDefaultTimNotHDSMonth() {
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    Map<String, Object> filterMaps = new HashMap<>();
    Calendar startTime = Calendar.getInstance();
    startTime.setTime(new Date());
    startTime.set(Calendar.DATE, startTime.get(Calendar.DATE) - 29);
    filterMaps.put("startTime", format.format(startTime.getTime()));
    filterMaps.put("endTime", format.format(new Date()));
    return filterMaps;
  }
}
